home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / doom / quake2.zip / QJOE19.ZIP / SUBS.QC < prev    next >
Text File  |  1996-08-14  |  6KB  |  318 lines

  1.  
  2.  
  3. void() SUB_Null = {};
  4.  
  5. void() SUB_Remove = {remove(self);};
  6.  
  7. .float  ishead;
  8. float   QJ_TEETH                 = 256;
  9. /*
  10. QuakeEd only writes a single float for angles (bad idea), so up and down are
  11. just constant angles.
  12. */
  13. vector() SetMovedir =
  14. {
  15.     if (self.angles == '0 -1 0')
  16.         self.movedir = '0 0 1';
  17.     else if (self.angles == '0 -2 0')
  18.         self.movedir = '0 0 -1';
  19.     else
  20.     {
  21.         makevectors (self.angles);
  22.         self.movedir = v_forward;
  23.     }
  24.     
  25.     self.angles = '0 0 0';
  26. };
  27.  
  28. /*
  29. ================
  30. InitTrigger
  31. ================
  32. */
  33. void() InitTrigger =
  34. {
  35. // trigger angles are used for one-way touches.  An angle of 0 is assumed
  36. // to mean no restrictions, so use a yaw of 360 instead.
  37.     if (self.angles != '0 0 0')
  38.         SetMovedir ();
  39.     self.solid = SOLID_TRIGGER;
  40.     setmodel (self, self.model);    // set size and link into world
  41.     self.movetype = MOVETYPE_NONE;
  42.     self.modelindex = 0;
  43.     self.model = "";
  44. };
  45.  
  46. /*
  47. =============
  48. SUB_CalcMove
  49.  
  50. calculate self.velocity and self.nextthink to reach dest from
  51. self.origin traveling at speed
  52. ===============
  53. */
  54. void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
  55. {
  56. local entity    stemp;
  57.     stemp = self;
  58.     self = ent;
  59.  
  60.     SUB_CalcMove (tdest, tspeed, func);
  61.     self = stemp;
  62. };
  63.  
  64. void(vector tdest, float tspeed, void() func) SUB_CalcMove =
  65. {
  66. local vector    vdestdelta;
  67. local float             len, traveltime;
  68.  
  69.     if (!tspeed)
  70.         objerror("No speed is defined!");
  71.  
  72.     self.think1 = func;
  73.     self.finaldest = tdest;
  74.     self.think = SUB_CalcMoveDone;
  75.  
  76.     if (tdest == self.origin)
  77.     {
  78.         self.velocity = '0 0 0';
  79.         self.nextthink = self.ltime + 0.1;
  80.         return;
  81.     }
  82.         
  83. // set destdelta to the vector needed to move
  84.     vdestdelta = tdest - self.origin;
  85.     
  86. // calculate length of vector
  87.     len = vlen (vdestdelta);
  88.     
  89. // divide by speed to get time to reach dest
  90.     traveltime = len / tspeed;
  91.  
  92.     if (traveltime < 0.1)
  93.     {
  94.         self.velocity = '0 0 0';
  95.         self.nextthink = self.ltime + 0.1;
  96.         return;
  97.     }
  98.     
  99. // set nextthink to trigger a think when dest is reached
  100.     self.nextthink = self.ltime + traveltime;
  101.  
  102. // scale the destdelta vector by the time spent traveling to get velocity
  103.     self.velocity = vdestdelta * (1/traveltime);    // qcc won't take vec/float     
  104. };
  105.  
  106. /*
  107. ============
  108. After moving, set origin to exact final destination
  109. ============
  110. */
  111. void()  SUB_CalcMoveDone =
  112. {
  113.     setorigin(self, self.finaldest);
  114.     self.velocity = '0 0 0';
  115.     self.nextthink = -1;
  116.     if (self.think1)
  117.         self.think1();
  118. };
  119.  
  120.  
  121. /*
  122. =============
  123. SUB_CalcAngleMove
  124.  
  125. calculate self.avelocity and self.nextthink to reach destangle from
  126. self.angles rotating 
  127.  
  128. The calling function should make sure self.think is valid
  129. ===============
  130. */
  131. void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
  132. {
  133. local entity            stemp;
  134.     stemp = self;
  135.     self = ent;
  136.     SUB_CalcAngleMove (destangle, tspeed, func);
  137.     self = stemp;
  138. };
  139.  
  140. void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
  141. {
  142. local vector    destdelta;
  143. local float             len, traveltime;
  144.  
  145.     if (!tspeed)
  146.         objerror("No speed is defined!");
  147.         
  148. // set destdelta to the vector needed to move
  149.     destdelta = destangle - self.angles;
  150.     
  151. // calculate length of vector
  152.     len = vlen (destdelta);
  153.     
  154. // divide by speed to get time to reach dest
  155.     traveltime = len / tspeed;
  156.  
  157. // set nextthink to trigger a think when dest is reached
  158.     self.nextthink = self.ltime + traveltime;
  159.  
  160. // scale the destdelta vector by the time spent traveling to get velocity
  161.     self.avelocity = destdelta * (1 / traveltime);
  162.     
  163.     self.think1 = func;
  164.     self.finalangle = destangle;
  165.     self.think = SUB_CalcAngleMoveDone;
  166. };
  167.  
  168. /*
  169. ============
  170. After rotating, set angle to exact final angle
  171. ============
  172. */
  173. void() SUB_CalcAngleMoveDone =
  174. {
  175.     self.angles = self.finalangle;
  176.     self.avelocity = '0 0 0';
  177.     self.nextthink = -1;
  178.     if (self.think1)
  179.         self.think1();
  180. };
  181.  
  182.  
  183. //=============================================================================
  184.  
  185. void() DelayThink =
  186. {
  187.     activator = self.enemy;
  188.     SUB_UseTargets ();
  189.     remove(self);
  190. };
  191.  
  192. /*
  193. ==============================
  194. SUB_UseTargets
  195.  
  196. the global "activator" should be set to the entity that initiated the firing.
  197.  
  198. If self.delay is set, a DelayedUse entity will be created that will actually
  199. do the SUB_UseTargets after that many seconds have passed.
  200.  
  201. Centerprints any self.message to the activator.
  202.  
  203. Removes all entities with a targetname that match self.killtarget,
  204. and removes them, so some events can remove other triggers.
  205.  
  206. Search for (string)targetname in all entities that
  207. match (string)self.target and call their .use function
  208.  
  209. ==============================
  210. */
  211. void() SUB_UseTargets =
  212. {
  213.     local entity t, stemp, otemp, act;
  214.  
  215. //
  216. // check for a delay
  217. //
  218.     if (self.delay)
  219.     {
  220.     // create a temp object to fire at a later time
  221.         t = spawn();
  222.         t.classname = "DelayedUse";
  223.         t.nextthink = time + self.delay;
  224.         t.think = DelayThink;
  225.         t.enemy = activator;
  226.         t.message = self.message;
  227.         t.killtarget = self.killtarget;
  228.         t.target = self.target;
  229.         return;
  230.     }
  231.     
  232.     
  233. //
  234. // print the message
  235. //
  236.     if (activator.classname == "player" && self.message != "")
  237.     {
  238.         centerprint (activator, self.message);
  239.         if (!self.noise)
  240.             sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
  241.     }
  242.  
  243. //
  244. // kill the killtagets
  245. //
  246.     if (self.killtarget)
  247.     {
  248.         t = world;
  249.         do
  250.         {
  251.             t = find (t, targetname, self.killtarget);
  252.             if (!t)
  253.                 return;
  254.             remove (t);
  255.         } while ( 1 );
  256.     }
  257.     
  258. //
  259. // fire targets
  260. //
  261.     if (self.target)
  262.     {
  263.         act = activator;
  264.         t = world;
  265.         do
  266.         {
  267.             t = find (t, targetname, self.target);
  268.             if (!t)
  269.             {
  270.                 return;
  271.             }
  272.             stemp = self;
  273.             otemp = other;
  274.             self = t;
  275.             other = stemp;
  276.             if (self.use != SUB_Null)
  277.             {
  278.                 if (self.use)
  279.                     self.use ();
  280.             }
  281.             self = stemp;
  282.             other = otemp;
  283.             activator = act;
  284.         } while ( 1 );
  285.     }
  286.     
  287.  
  288. };
  289.  
  290.  
  291. /*
  292.  
  293. in nightmare mode, all attack_finished times become 0
  294. some monsters refire twice automatically
  295.  
  296. */
  297.  
  298. void(float normal) SUB_AttackFinished =
  299. {
  300.     self.cnt = 0;           // refire count for nightmare
  301.     if (skill != 3)
  302.         self.attack_finished = time + normal;
  303. };
  304.  
  305. float (entity targ) visible;
  306.  
  307. void (void() thinkst) SUB_CheckRefire =
  308. {
  309.     if (skill != 3)
  310.         return;
  311.     if (self.cnt == 1)
  312.         return;
  313.     if (!visible (self.enemy))
  314.         return;
  315.     self.cnt = 1;
  316.     self.think = thinkst;
  317. };
  318.